﻿// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php

using System.Collections.Generic;
using System.Windows.Media;

using Nova.CodeDOM;

namespace Nova.UI
{
    /// <summary>
    /// The view model for a <see cref="CodeDOM.CompilerDirective"/>.
    /// </summary>
    public abstract class CompilerDirectiveVM : AnnotationVM
    {
        #region /* CONSTRUCTORS */

        /// <summary>
        /// Create a view model instance for the specified <see cref="CodeDOM.CompilerDirective"/>.
        /// </summary>
        protected CompilerDirectiveVM(CompilerDirective compilerDirective, Dictionary<CodeObject, CodeObjectVM> dictionary)
            : base(compilerDirective, dictionary)
        { }

        #endregion

        #region /* PROPERTIES */

        /// <summary>
        /// The underlying <see cref="CodeDOM.CompilerDirective"/> model.
        /// </summary>
        public CompilerDirective CompilerDirective
        {
            get { return (CompilerDirective)CodeObject; }
        }

        #endregion

        #region /* RENDERING */

        public override Brush BorderBrush
        {
            get { return Brushes.LightPink; }
        }

        public override Brush BackgroundBrush
        {
            get { return Brushes.MistyRose; }
        }

        public override int BorderHPad
        {
            get { return 2; }
        }

        public override int BorderVPad
        {
            get { return 1; }
        }

        protected virtual void RenderArgument(CodeRenderer renderer, RenderFlags flags)
        { }

        protected virtual void RenderSkippedText(CodeRenderer renderer, RenderFlags flags)
        { }

        public override void Render(CodeRenderer renderer, RenderFlags flags)
        {
            int newLines = CompilerDirective.NewLines;

            // Compiler directives always start on a new line (but still check for IsPrefix)
            bool isPrefix = flags.HasFlag(RenderFlags.IsPrefix);
            if (!isPrefix && !flags.HasFlag(RenderFlags.SuppressNewLine))
                renderer.NewLines(newLines < 1 ? 1 : newLines, ParentVM);

            CreateBorder(renderer, flags);

            RenderFlags passFlags = (flags & RenderFlags.PassMask);
            RenderBefore(renderer, passFlags | RenderFlags.IsPrefix);

            renderer.RenderText(CompilerDirective.ParseToken + CompilerDirective.DirectiveKeyword, DIRECTIVE_BRUSH, this);
            if (CompilerDirective.HasArgument)
            {
                renderer.RenderText(" ", PUNC_BRUSH, this);
                RenderArgument(renderer, passFlags | RenderFlags.ForceBorder);
            }

            RenderEOLComments(renderer, flags);
            RenderAfter(renderer, passFlags | (flags & RenderFlags.NoPostAnnotations));

            renderer.ReturnToBorderParent(this);

            // If this directive is rendered as a prefix, then the newline comes at the end
            if (isPrefix)
                renderer.NewLines(newLines < 1 ? 1 : newLines, ParentVM);
            else
                renderer.NeedsNewLine = true;

            RenderSkippedText(renderer, flags);
        }

        #endregion
    }
}
